package com.shouxin.attendance.serialport;

import android.os.SystemClock;
import android.text.TextUtils;

import com.shouxin.attendance.constants.CommonConstants;

import org.apache.log4j.Logger;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import android_serialport_api.SerialPort;

public final class SerialManager {

	private static final Logger logger = Logger.getLogger(SerialManager.class);

	private static final String SERIAL_PATH = "/dev/ttyS2";

	private static final int SERIAL_BAUDRATE = 115200;

	private SerialPort mSerialPort;

	private OutputStream mOutputStream;

	private InputStream mInputStream;

	private ReadThread mReadThread;

	private boolean isStop = false;

	private HashMap<String, DataHandler> handlers = new HashMap<>();

	private SerialManager() {
		handlers.put(CommonConstants.PORT_1, new DataHandler(CommonConstants.PORT_1));
		handlers.put(CommonConstants.PORT_2, new DataHandler(CommonConstants.PORT_2));
		handlers.put(CommonConstants.PORT_3, new DataHandler(CommonConstants.PORT_3));
		handlers.put(CommonConstants.PORT_4, new DataHandler(CommonConstants.PORT_4));
	}

	public static SerialManager getInstance() {
		return Instance.instance;
	}

	private static byte[] hexStringToByte(String hexString) {
		if (hexString == null || hexString.equals("")) {
			return null;
		}
		hexString = hexString.toUpperCase();
		int length = hexString.length() / 2;
		char[] hexChars = hexString.toCharArray();
		byte[] d = new byte[length];
		for (int i = 0; i < length; i++) {
			int pos = i * 2;
			d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
		}
		return d;
	}

	private static byte charToByte(char c) {
		return (byte) "0123456789ABCDEF".indexOf(c);
	}

	/**
	 * 初始化串口信息
	 */
	public void onCreate() {
		try {
			mSerialPort = new SerialPort(new File(SERIAL_PATH), SERIAL_BAUDRATE);
			mOutputStream = mSerialPort.getOutputStream();
			mInputStream = mSerialPort.getInputStream();

			mReadThread = new ReadThread();
			isStop = false;
			mReadThread.start();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 关闭串口
	 */
	@SuppressWarnings("unused")
	public void closeSerialPort() {
		isStop = true;
		if (mReadThread != null) {
			mReadThread.interrupt();
		}
		if (mSerialPort != null) {
			mSerialPort.close();
		}
	}

	/**
	 * 发送指令到串口
	 */
	boolean sendCmds(String cmd) {
		logger.debug("[sendCmds] cmd =>" + cmd);
		if (TextUtils.isEmpty(cmd)) {
			logger.error("发送的指令为空...");
			return false;
		}
		boolean result = true;
		byte[] bytes = hexStringToByte(cmd);
		if (bytes != null) {
			try {
				if (mOutputStream != null) {
					mOutputStream.write(bytes);
					logger.debug("告警指令发送完成...");
				} else {
					result = false;
				}
			} catch (IOException e) {
				logger.debug("告警指令发送异常 =>", e);
				result = false;
			}
		} else {
			result = false;
		}
		return result;
	}

	private static class Instance {

		private static SerialManager instance = new SerialManager();
	}

	private class ReadThread extends Thread {

		private static final int RECORD_LENGTH = 34;

		private String dataSum = "";

		@Override
		public void run() {
			while (!isStop && !isInterrupted()) {
				int size;
				try {
					byte[] buffer = new byte[mInputStream.available()];
					size = mInputStream.read(buffer);
					if (size > 0) {
						StringBuilder localStringBuilder = new StringBuilder();
						for (int j = 0; j < size; j++) {
							localStringBuilder.append(String.format("%02x", buffer[j]).toUpperCase());
						}
						logger.debug("data is:" + localStringBuilder.toString());
						String data = localStringBuilder.toString();
						dataSum += data;

						Pattern pattern = Pattern.compile("((A1){3}|(A2){3}|(A3){3}|(A4){3}|(A5){3}|(A6){3})5A");
						Matcher matcher = pattern.matcher(dataSum);
						if (matcher.find()) {
							dataSum = dataSum.substring(matcher.start());
						} else {
							if (dataSum.length() > RECORD_LENGTH) {
								dataSum = "";
							}
							continue;
						}
						logger.debug("last data size is :" + dataSum.length() + " | " + dataSum);

						int n = dataSum.length() / RECORD_LENGTH;
						for (int i = 0; i < n; i++) {
							String subData = dataSum.substring(0, RECORD_LENGTH);
							String port = subData.substring(0, 6);
							DataHandler dataHandler = handlers.get(port);
							if (null != dataHandler) {
								dataHandler.onDataReceive(subData.substring(6));
							} else {
								logger.error("串口号不支持：" + port);
							}
							dataSum = dataSum.substring(RECORD_LENGTH);
						}
					}
					SystemClock.sleep(20);
				} catch (Exception e) {
					logger.error("[ReadThread]:exception", e);
					return;
				}
			}
		}
	}

}
